using System;
using NUnit.Framework;
using System.Collections.Generic;

namespace Tests
{
	[TestFixture]
	public class TestDirectionalPhongLight
	{		
		OpenRay.PhongMaterial material;
		
		[SetUp]
		public void Init ()
		{
			OpenRay.Color[] ambient = new OpenRay.Color[2];
			OpenRay.Color[] diffuse = new OpenRay.Color[2];
			OpenRay.Color[] specular = new OpenRay.Color[2];
			OpenRay.Color[] emissive = new OpenRay.Color[2];
			float[] shininess = new float[2];
			
			ambient[0] = new OpenRay.Color( 0.2f, 0.2f, 0.2f, 1f );
			ambient[1] = new OpenRay.Color( 0.2f, 0.2f, 0.2f, 1f );
			
			diffuse[0] = new OpenRay.Color( 0.8f, 0.8f, 0.8f, 1f );
			diffuse[1] = new OpenRay.Color( 0.8f, 0.8f, 0.8f, 1f );
			
			specular[0] = new OpenRay.Color( 0.0f, 0.0f, 0.0f, 1f );
			specular[1] = new OpenRay.Color( 0.0f, 0.0f, 0.0f, 1f );
			
			emissive[0] = new OpenRay.Color( 0.0f, 0.0f, 0.0f, 1f );
			emissive[1] = new OpenRay.Color( 0.0f, 0.0f, 0.0f, 1f );
			
			shininess[0] = 0f;
			shininess[1] = 0f;
			
			material = new OpenRay.PhongMaterial(ambient, diffuse, specular, emissive, shininess);
		}
		
		[Test]
		public void TestDirectionalLight() {
			IList<OpenRay.Light> lights = new List<OpenRay.Light>();
			
			lights.Add( new OpenRay.DirectionalPhongLight( new OpenRay.Color( 0f, 0f, 0f, 1f ),
                                               			   new OpenRay.Color( 1f, 1f, 1f, 1f ),
                                               			   new OpenRay.Color( 1f, 1f, 1f, 1f ),
                                               			   new OpenRay.Vector( 0, 0, 1 ), null ) );
			
			OpenRay.Vector surfaceNormal = new OpenRay.Vector( 0f, (float)Math.Sqrt(3), 1f );
			surfaceNormal = OpenRay.Vector.Normalize( surfaceNormal );
			
			OpenRay.Color act = material.Shade( new OpenRay.Point( 0f, 0f, 0f, 1f ),
			                                    new OpenRay.Point( 0f, 0f, 0f, 1f ),
			                                    new OpenRay.Vector( 0f, 0f, 1f ),
			                                    surfaceNormal, lights, 1 );
			
			OpenRay.Color expected = new OpenRay.Color( 0.4f, 0.4f, 0.4f, 3.5f );
			
			Assert.AreEqual( expected, act );
		}
		
		[Test]
		public void TestDirectionalLightBackSide() {
			IList<OpenRay.Light> lights = new List<OpenRay.Light>();
			
			lights.Add( new OpenRay.DirectionalPhongLight( new OpenRay.Color( 0f, 0f, 0f, 1f ),
                                               	     	   new OpenRay.Color( 1f, 1f, 1f, 1f ),
                                               	     	   new OpenRay.Color( 1f, 1f, 1f, 1f ),
                                               	     	   new OpenRay.Vector( 0, 0, -1 ), null ) );
			
			OpenRay.Vector surfaceNormal = new OpenRay.Vector( 0f, (float)Math.Sqrt(3), 1f );
			surfaceNormal = OpenRay.Vector.Normalize( surfaceNormal );
			
			OpenRay.Color act = material.Shade( new OpenRay.Point( 0f, 0f, 0f, 1f ),
			                                    new OpenRay.Point( 0f, 0f, 0f, 1f ),
			                                    new OpenRay.Vector( 0f, 0f, 1f ),
			                                    surfaceNormal, lights, 1 );
			
			OpenRay.Color expected = new OpenRay.Color( 0.0f, 0.0f, 0.0f, 3f );
			
			Assert.AreEqual( expected, act );
		}
	}
}

